
{
  //引入泛型
  //声明一个函数 创建 n 个 m 组成的数组
  function createArray(n:number, m: any){
    //声明一个空数组
    let result: any[] = [];
    //循环
    for(let i=0; i<n; i++){
      result.push(m);
    }
    //返回 result 数组
    return result;
  }
  //调用函数
  let arr1 = createArray(3, 'love');
  let arr2 = createArray(3, 3);
  // arr1[0].slice(0, 2)
  // arr2[0].slice(0, 2);
}

{
  class User {
    name: string;
    constructor(name: string){
      this.name = name;
    }
  }

  //泛型的初体验 T 泛型参数. 名字自由, 一般使用的泛型参数有 T, V, P, K  abcd 也可以
  //泛型函数
  function createArray<T>(n:number, m: T):T[]{
    //声明一个空数组
    let result: T[] = [];
    //循环
    for(let i=0; i<n; i++){
      result.push(m);
    }
    //返回 result 数组
    return result;
  }

  //调用函数
  let arr1 = createArray<string>(3, 'love');
  // arr1[0].slice(0, 2);//这里已经有提示了
  let arr2 = createArray<number>(3, 1);
  // console.log(arr2[0].toFixed(2));
  let arr3 = createArray<User>(3, new User('xx'));
  console.log(arr3);
  
}

{
  function createArray<T, K>(a: T, b: K):[T, K]{
    return [a, b];
  }

  //调用函数
  let res = createArray<string, number>('baby', 360);

  // console.log(res[0].toUpperCase()); //有代码提示  
  // res[1].slice() // 如果不小心写错了, 也会有错误提示
}

{
  // 泛型接口
  interface Response<T>{
    status: number;
    headers: object;
    data: T;
  }

  interface User{
    id: number;
    name: string;
    age: number;
  }

  interface Book{
    id: number;
    title: string;
    price: number;
  }

  interface Movie{
    id: number;
    title: string;
    director: string;
    actors: string[]
  }

  //声明一个对象
  let response: Response<User> = {
    status: 200,
    headers: {
      'content-type': 'text/html;charset=utf-8'
    },
    data: {
      id: 1,
      name: 'zhangsan',
      age: 18
    }
  }

  let response2: Response<Book> = {
    status: 200,
    headers: {
      'content-type': 'text/html;charset=utf-8'
    },
    data: {
      id: 1,
      title: '西游记',
      price: 19.9
    }
  }

  let response3: Response<Movie> = {
    status: 200,
    headers: {
      'content-type': 'text/html;charset=utf-8'
    },
    data: {
      id: 1,
      title: '流浪地球 2',
      director: '郭凡',
      actors: ['吴京', '王智', '刘德华']
    }
  }

  // response3.data.director
  // async function fetchData(){
  //   let result:Response<Movie> = await axios.get('http://api.xiaohigh.com/book');
  // }



}

{
  interface Response<T>{
    status: number;
    headers: object;
    data: T
  }

  interface ResponseBody<T>{
    code: string;
    msg: string;
    data: T
  }

  interface User{
    id: number;
    name: string;
    age: number;
  }

  interface Book{
    id: number;
    title: string;
    price: number;
  }

  //泛型接口
  let response: Response<ResponseBody<User>> = {
    status: 200,
    headers: {
      'content-type': 'text/html;charset=utf-8'
    },
    data: {
      code: '0000',
      msg: '获取成功',
      data: {
        id: 1,
        name: 'lisi',
        age: 18
      }
    }
  }

  let response2:Response<ResponseBody<Book>> = {
    status: 200,
    headers: {
      'content-type': 'text/html;charset=utf-8'
    },
    data: {
      code: '0000',
      msg: '获取成功',
      data: {
        id: 2,
        title: '三体',
        price: 39
      }
    }
  }

}

{
  class Container<T>{
    //数据的初始化
    store: T[] = [];

    //方法
    //向数组中添加元素
    insert(arg: T){
      this.store.push(arg);
    }

    getAll(): T[]{
      return this.store;
    }
  }

  let c = new Container<string>();

  c.getAll().forEach(item => {
    //这里 item 是有代码提示的
  })

}

{
  interface LengthMast{
    length: number;
  }

  //泛型约束
  function getLength<T extends LengthMast>(arg: T){
    return arg.length;
  }

  getLength('xxx')// OK
  // getLength(123);
  getLength([1,2,3,4]);
  getLength<number[]>([1,2,3,4]);
}